﻿//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using System.Threading;
using System.Collections.Generic;
using Wicresoft.SelfService.WFInterface;

namespace Wicresoft.SelfService.WFHost.Code
{

    /// <summary>
    /// This class is helper to deal with all IO related issues (folders, paths, etc.)
    /// </summary>
    public static class IOHelper
    {
        public static readonly string InstanceFormatString = "{0}.xml";
        public static readonly string PersistenceDirectory = Path.Combine(Path.GetTempPath(), "FileServicesApprove");
        private static ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim();

        public static string GetFileName(Guid id)
        {
            EnsurePersistenceFolderExists();
            return Path.Combine(PersistenceDirectory, string.Format(CultureInfo.InvariantCulture, InstanceFormatString, id));
        }

        public static string GetAllInstanceIdsFileName()
        {
            EnsurePersistenceFolderExists();
            return Path.Combine(PersistenceDirectory, "InstanceId.xml");
        }

        public static string GetResultFileName()
        {
            EnsurePersistenceFolderExists();
            return Path.Combine(PersistenceDirectory, "Results.xml");
        }

        public static void EnsurePersistenceFolderExists()
        {
            if (!Directory.Exists(PersistenceDirectory))
            {
                Directory.CreateDirectory(PersistenceDirectory);
            }
        }

        public static void EnsureAllInstanceIdFileExists()
        {
            string fileName = IOHelper.GetAllInstanceIdsFileName();
            if (!File.Exists(fileName))
            {
                XElement root = new XElement("InstanceIds");
                root.Save(fileName);
            }
        }

        public static void EnsureAllResultFileExists()
        {
            string fileName = IOHelper.GetResultFileName();
            if (!File.Exists(fileName))
            {
                XElement root = new XElement("Results");
                root.Save(fileName);
            }
        }

        public static XElement Load()
        {
            cacheLock.EnterReadLock();
            try
            {
                EnsureAllResultFileExists();
                return XElement.Load(GetResultFileName());
            }
            finally
            {
                cacheLock.ExitReadLock();
            }
        }

        public static void Save(Guid Id, string status, ActionResult actionResult)
        {
            cacheLock.EnterWriteLock();
            try
            {
                string fileName = GetResultFileName();
                XElement doc = XElement.Load(fileName);

                IEnumerable<XElement> current =
                                        from r in doc.Elements("Result")
                                        where r.Attribute("id").Value.Equals(Id.ToString())
                                        select r;


                if (status == "Closed")
                {
                    foreach (XElement xe in current)
                    {
                        xe.Attribute("status").Value = "finished";
                    }
                }
                else
                {
                    foreach (XElement xe in current)
                    {
                        xe.Remove();
                    }

                    if (actionResult != null)
                    {
                        XElement e = Serialize(actionResult, Id);
                        doc.Add(e);
                    }
                }

                doc.Save(fileName);
            }
            finally
            {
                cacheLock.ExitWriteLock();
            }
        }

        static XElement Serialize(ActionResult actionResult, Guid instanceId)
        {
            // main body of the ActionResult
            XElement ret =
               new XElement("Result",
                   new XAttribute("id", instanceId.ToString()),
                   new XAttribute("status", "active"),
                       new XElement("ErrorMsg", actionResult.ErrorMsg),
                       new XElement("Step", actionResult.Step),
                       new XElement("WFStatus", actionResult.Status),
                       new XElement("RequestCode", actionResult.RequestCode));

            return ret;
        }
    }
}
